// 创建birds.js
var express = require('express')
var multer = require("multer");
const StringDecoder = require('string_decoder').StringDecoder;
var multiparty = require("multiparty");

var gzipApi = express.Router()// 创建一个路由实例
const fs = require('fs');
const zlib = require('zlib');
const path = require('path');

const PUBLIC_PATH = path.resolve(__dirname, "../public");
var storage = multer.diskStorage({
    //保存路径
    destination: function (req, file, cb) {
        cb(null, "./public/upload");
    },
    //保存在 destination 中的文件名
    filename: function (req, file, cb) {
        cb(null, file.originalname);
    },
});
var uploads = multer({ storage: storage });


function ungzip($src) {
    fs.stat($src, function (err, stats) {
        if (stats.isFile()) {
            let rs = fs.createReadStream($src);
            //zlib.createGunzip()创建一个gunzip转换流
            $dst = path.join(__dirname, path.basename($src, '.gz'));
            rs.pipe(zlib.createGunzip()).pipe(fs.createWriteStream($dst));
        }
    });
}


// 中间件功能
gzipApi.use(function timeLog(req, res, next) {
    console.log('Time: ', new Date().toLocaleString())
    next()
})
// 访问/gzipApi
gzipApi.post('/', function (req, res) {
    console.log('zdy-----headers：------>' + JSON.stringify(req.headers))
    console.log('zdy-----path------>' + JSON.stringify(req.path))
    console.log('zdy-----baseUrl------>' + JSON.stringify(req.baseUrl))
    let requestPath = ''
    if (req.baseUrl != undefined && req.baseUrl != '' && req.baseUrl != null && req.baseUrl.trim().length > 0) {
        requestPath = req.baseUrl
    } else if (req.path != undefined && req.path != '' && req.path != null && req.path.trim().length > 0) {
        requestPath = req.path
    }
    let requestUrl = ''
    if ('http' === req.protocol) {
        requestUrl = 'http://' + req.hostname + requestPath
    } else {
        requestUrl = 'https://' + req.hostname + requestPath
    }
    console.log('zdy-----requestUrl------>' + requestUrl)
    let responseMsg = '请求：' + requestUrl + '成功'
    res.json({
        header: req.headers,
        body: req.body,
        method: req.method,
        url: req.baseUrl,
        msg: responseMsg
    })
})

// 访问/postGzip
gzipApi.post('/postGzip', function (req, res) {

    console.log('zdy-----headers：------>' + JSON.stringify(req.headers))
    console.log('zdy-----path------>' + JSON.stringify(req.path))
    console.log('zdy-----baseUrl------>' + JSON.stringify(req.baseUrl))
    let msg = [];
    req.on("data", (chunk) => {
        if (chunk) {
            console.log('zdy-----chunk------>' + "chunk;", chunk);
            let buf = Buffer.from(chunk)
            console.log('zdy-----chunk------>' + "chunk-string;", buf.toString('utf-8'));
            msg.push(chunk);
        }
    })
    req.on('end', () => {
        // 对buffer数组阵列列表进行buffer合并返回一个Buffer
        let buf = Buffer.concat(msg);
        console.log('zdy-----buf------>' + (typeof buf))
        let str = buf.toString('utf-8')
        console.log('zdy-----end------>' + str)//提取Buffer正确
        zlib.unzip(buf, function (err, resiltArr) {
            console.log('zdy-----err------>' + err)
            console.log('zdy-----resiltArr------>' + resiltArr)
            // let newBody = resiltArr.toString('utf-8')
            // console.log('zdy-----unzip------>' + newBody)
            // let obj = {
            //     method: req.method,
            //     url: req.baseUrl,
            //     msg: '200',
            //     header: req.headers,
            //     body: newBody,

            // }
            // let str = JSON.stringify(obj)
            const buffer = Buffer.from("server give you message");
            // res.send(buf)

            zlib.gzip(buffer, function (err, result) {
                console.log('zdy-----err------>' + err)
                console.log('zdy-----result------>' + result)
                const decoder = new StringDecoder('utf8');
                const str = decoder.write(result);
                console.log('zdy-----gzip result------>' + str)
                res.setHeader("Content-Encoding", 'gzip');
                res.send(result)
            })

        })

    })

})


// 访问/getGzip
gzipApi.get('/getGzip', function (req, res) {
    console.log('zdy-----headers：------>' + JSON.stringify(req.headers))
    const buf = Buffer.from("server give you message");
    // res.send(buf)
    zlib.gzip('server give client gzip content', function (err, result) {
        console.log('zdy-----err------>' + err)
        console.log('zdy-----gzip result------>' + result.toString('utf-8'))
        res.setHeader("Content-Encoding", 'gzip');
        res.send(result)
        zlib.unzip(result, function (err, data) {
            console.log('zdy-----unzip result------>' + data.toString('utf-8'))
        })

    })
})


// 访问/uploadGzipFile
gzipApi.post('/uploadGzipFile', function (req, res) {
    console.log('zdy-----headers：------>' + JSON.stringify(req.headers))
    const form = new multiparty.Form()
    form.parse(req, (err, field, files) => {
        try {
            console.log('-----field------>' + JSON.stringify(field));
            console.log('-----files------>' + JSON.stringify(files));
            if (err) {
                console.log('zdy-----err------>' + JSON.stringify(err));
                res.send(err);
                return;
            }
            if (!fs.existsSync('./public/upload')) {
                fs.mkdirSync('./public/upload')
            }
            if (files && Object.keys(files).length === 0) {
                console.log('zdy-----没有上传文件------>');
                res.send('-----没有上传文件------>');
                return;
            }

            writeFileByfs(files).then((data) => {
                console.log('zdy-----writeFileByfs  data------>' + data);
                res.status(200)
                res.send({
                    header: req.headers,
                    body: req.body,
                    method: req.method,
                    fieldBack: field,
                    filesBack: files,
                    url: req.originalUrl,
                    msg: "上传成功"
                })
            }).catch((err) => {
                console.log('zdy-----writeFileByfs JSON err------>' + JSON.stringify(err));
                console.log('zdy-----writeFileByfs  err------>' + err);
                res.status(400)
                res.send("上传失败")
            })

        } catch (error) {
            console.log('zdy-----JSON error------>' + JSON.stringify(error));
            console.log('zdy-----writeFileByfs  error------>' + error);
            res.send(error);
        }



    })
})

function writeFileByfs(files) {
    let keys = Object.keys(files)
    console.log('zdy-----writeFileByfs  keys------>' + JSON.stringify(keys));
    let promises = [];
    function generatePromise(file) {
        return new Promise((resolve, reject) => {
            const fileName = file.originalFilename;
            console.log('zdy-----writeFileByfs  fileName------>' + fileName);
            const filePath = file.path;
            let writePath = "./public/upload/" + fileName;
            if (!fs.existsSync(writePath)) {
                fs.writeFileSync(writePath, '', 'utf-8');
            }
            const writeable = fs.createWriteStream(writePath);
            const readable = fs.createReadStream(filePath);

            readable.pipe(writeable);
            readable.on('end', () => {
                resolve(true);
                ungzip(writePath);
            })
            readable.on('err', () => {
                reject(false);
            })
        })
    }
    for (let i = 0; i < keys.length; i++) {
        console.log('\r\n');
        console.log('\r\n');
        console.log('zdy-----writeFileByfs  keys[i]------>' + JSON.stringify(keys[i]));
        let tempFile = files[keys[i]]
        console.log('zdy-----writeFileByfs  tempFile------>' + JSON.stringify(tempFile));
        console.log('\r\n');
        for (let j = 0; j < tempFile.length; j++) {
            promises.push(generatePromise(tempFile[j]))
        }

    }
    return Promise.all(promises);
}
function ungzip($src) {
    fs.stat($src, function (err, stats) {
        if (stats.isFile()) {
            let rs = fs.createReadStream($src);
            //zlib.createGunzip()创建一个gunzip转换流
            $dst = path.join(__dirname, path.basename($src, '.gz'));
            console.log('zdy-----writeFileByfs  dst------>' + $dst);
            rs.pipe(zlib.createGunzip()).pipe(fs.createWriteStream($dst));
            console.log('zdy-----writeFileByfs  解压完成------>');
        }
    });
}

// 访问/postGzipContent
gzipApi.get('/download/gzip/:path', uploads.single("file"), function (req, res) {

    let downloadPath = './public/download/test.txt'
    let tempPath = './public/download/test.txt.gz'
    let isExsit = fs.existsSync(tempPath);
    console.log('zdy-----isExsit------>' + isExsit)
    // 获取参数
    let filePath = req.params.path;
    // 拼接文件的绝对路径

    // 得到文件名
    let { base: fileName } = path.parse(tempPath);
    console.info(fileName)

    // 文件的信息
    let stat;
    try {
        // 通过fs模块获取文件的信息，报错就代表着不存在该文件
        stat = fs.statSync(tempPath);
        console.log(stat.size);
        res.setHeader("content-length", stat.size);
    } catch (error) {
        // 不存在该文件
        return res.status(404).end();
    }

    // 获取文件的大小
    let { size: total } = stat;
    // 设置响应头信息，指示内容应该被下载
    res.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
    res.setHeader(
        "Content-Disposition",
        "attachment; filename=" + encodeURIComponent(fileName)
    );

    // 说明了实体主体内对象的媒体类型，这是一个二进制文件类型
    res.setHeader("Content-Type", "application/octet-stream");
    res.setHeader("ywp", "application/octet-stream");
    // 响应状态为200
    res.status(200);

    // 通过fs模块创建二进制流，并将其二进制流推送到响应主体中
    fs.createReadStream(tempPath).pipe(res);






})


module.exports = gzipApi